package com.hou.controller;

import com.google.common.util.concurrent.RateLimiter;
import com.hou.pojo.Stock;
import com.hou.service.OrderService;
import com.hou.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;

/**
 * @author shkstart
 * @create 2021-09-06-21:04
 */
@RestController
@RequestMapping("stock")
public class SeckillController {


    @Autowired
    private OrderService orderService;

    @Autowired
    @Qualifier("stringRedisTemplate")
    private StringRedisTemplate redis;

    @Autowired
    private UserService userService;


    // 创建令牌桶实例
    private RateLimiter rateLimiter = RateLimiter.create(1);


    // 乐观锁+限流+MD5校验+限制访问频率
    @GetMapping("kill_token/{userId}/{stockId}/{md5}")
    public String killTokenByMd5(@PathVariable("userId") Integer userId, @PathVariable("stockId") Integer stockId, @PathVariable("md5") String md5){

        // Redis控制秒杀时间
        if (!redis.hasKey("kill"+stockId)) {
            return "活动已经结束!";
        }

        // 令牌桶限流
        if(!rateLimiter.tryAcquire(2,TimeUnit.SECONDS)){
            System.out.println("秒杀失败！");
        }

        // 控制访问频率
        userService.saveUserCount(userId, stockId);

        if (!userService.isBeyond(userId, stockId)){
            return "访问过于频繁！";
        }

        try {
            int orderId = orderService.kill(userId,stockId,md5);
            return "秒杀成功,订单id为："+String.valueOf(orderId);
        } catch (Exception e){
            e.printStackTrace();
            return e.getMessage();
        }
    }

    // 开启指定商品指定时间的秒杀
    @RequestMapping("start_kill/{id}/{time}")
    public String StartKill(@PathVariable("id") Integer id,@PathVariable("time") Integer time){
        // 创建reids对象
        redis.opsForValue().set("kill"+id,"start",time,TimeUnit.SECONDS);

        // 获取商品信息
        Stock stock = orderService.getInformationById(id);
        String name = stock.getName();

        String res = name+"(id="+id+")"+"商品已经开始秒杀，持续时间为"+time+"s";
        return res;
    }

    // 生成MD5
    @RequestMapping("md5/{userId}/{stockId}")
    public String CreateMd5(@PathVariable("userId") Integer userId,@PathVariable("stockId") Integer stockId){

        String md5;

        try {
            md5 = orderService.getMd5(userId, stockId);
        } catch (Exception e){
            return "获取md5失败";
        }

        return md5;

    }

}
